// DlgSearch.cpp : implementation file
//

#include "stdafx.h"
#include "finance.h"
#include "financedef.h"
#include "CDataFile.h"
#include "DlgSearch.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


extern CFinanceApp theApp;       

/////////////////////////////////////////////////////////////////////////////
// CDlgSearch dialog


CDlgSearch::CDlgSearch(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgSearch::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDlgSearch)
	m_dateBegin = 0;
	m_dateEnd = 0;
	//}}AFX_DATA_INIT

	m_bExactMatch = FALSE;
	m_iCompare = 0; // default is equal
}


void CDlgSearch::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgSearch)
	DDX_DateTimeCtrl(pDX, IDC_DATE_BEG, m_dateBegin);
	DDX_DateTimeCtrl(pDX, IDC_DATE_END, m_dateEnd);
	DDX_Control(pDX, ID_SEARCH, m_btnSearch);
	DDX_Control(pDX, IDCANCEL, m_btnQuit);
	DDX_Control(pDX, IDC_CMB_FLOW, m_cmbFlow);
	DDX_Control(pDX, IDC_CMB_PURPOSE, m_cmbPurpose);
	DDX_Control(pDX, IDC_CMB_OWNER, m_cmbOwner);
	DDX_Control(pDX, IDC_ED_COMMENT, m_edComment);
	DDX_Control(pDX, IDC_ED_MONEY, m_edAccount);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgSearch, CDialog)
	//{{AFX_MSG_MAP(CDlgSearch)
	ON_BN_CLICKED(ID_SEARCH, OnSearch)
	ON_BN_CLICKED(IDC_RDO_EXACT, OnRdoExact)
	ON_BN_CLICKED(IDC_RDO_INEXACT, OnRdoInexact)
	ON_BN_CLICKED(IDC_CHK_FLOW, OnChkFlow)
	ON_BN_CLICKED(IDC_CHK_PURPOSE, OnChkPurpose)
	ON_BN_CLICKED(IDC_CHK_OWNER, OnChkOwner)
	ON_BN_CLICKED(IDC_CHK_DATE, OnChkDate)
	ON_CBN_SELCHANGE(IDC_CMB_FLOW, OnSelchangeCmbFlow)
	ON_BN_CLICKED(IDC_RDO_LESS, OnRdoLess)
	ON_BN_CLICKED(IDC_RDO_EQUAL, OnRdoEqual)
	ON_BN_CLICKED(IDC_RDO_MORE, OnRdoMore)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlgSearch message handlers

// 
// 
//--------------------------------------------------------------
BOOL CDlgSearch::OnInitDialog() 
{
	CDataFile		IniDF( MONEY_CFG );
	CButton			*pItemRadio;
	_variant_t		var;
	CString			csTmp;
	CString			csSQL;
	
	
	CDialog::OnInitDialog();
	
	// <> Init UI	
	m_btnSearch.SetIcon(IDI_EYEON, IDI_EYEOFF);
	m_btnQuit.SetIcon(IDI_CANCEL34,IDI_CANCEL32);
	
	// <> match style
	m_bExactMatch = IniDF.GetInt( "ExactMatch", "SQL segment" );	// 0 or 1
	if( m_bExactMatch )
		pItemRadio = (CButton*)GetDlgItem( IDC_RDO_EXACT );
	else
		pItemRadio = (CButton*)GetDlgItem( IDC_RDO_INEXACT );
	if( pItemRadio ) 
		pItemRadio->SetCheck( 1 );

	// <> compare method
	pItemRadio = (CButton*)GetDlgItem( IDC_RDO_EQUAL );
	if( pItemRadio ) 
		pItemRadio->SetCheck( 1 );
	
	// <> Open RecordSet
	m_pRecordset.CreateInstance(__uuidof(Recordset));
	

	// <> Fill ComboBox flowclass
	try
	{
		m_pRecordset->Open("SELECT * FROM Flowclass",   
			theApp.m_pConnection.GetInterfacePtr(),	 // Get the Ptr of connect lib
			adOpenDynamic,
			adLockOptimistic,
			adCmdText);
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	
	m_cmbFlow.ResetContent();
	try
	{
		if(!m_pRecordset->BOF)
			m_pRecordset->MoveFirst();
		else
		{
			//AfxMessageBox("Table is NULL");
			return TRUE;
		}
		
		while(!m_pRecordset->adoEOF)
		{
			var = m_pRecordset->GetCollect("Classname"); // txt
			if(var.vt != VT_NULL)
				csTmp = (LPCSTR)_bstr_t(var);
			
			m_cmbFlow.AddString( csTmp );
			
			m_pRecordset->MoveNext();
		}
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	m_cmbFlow.SetCurSel( 0 );
	m_pRecordset->Close();
	
	// <> Fill ComboBox Purpose
	m_cmbFlow.GetLBText( m_cmbFlow.GetCurSel(), csTmp );
	
	csSQL = "SELECT Usename FROM Purpose WHERE Flowclass='" + csTmp + "' ORDER BY Usename ASC";
	var = csSQL;
	try
	{
		m_pRecordset->Open( var,					// const _variant_t & Source
			theApp.m_pConnection.GetInterfacePtr(),	// Get the Ptr of connect lib
			adOpenDynamic,
			adLockOptimistic,
			adCmdText);
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	
	m_cmbPurpose.ResetContent();
	try
	{
		if(!m_pRecordset->BOF)
			m_pRecordset->MoveFirst();
		else
		{
			//AfxMessageBox("Table is NULL");
			return TRUE;
		}
		
		while(!m_pRecordset->adoEOF)
		{
			var = m_pRecordset->GetCollect("Usename"); // txt
			if(var.vt != VT_NULL)
				csTmp = (LPCSTR)_bstr_t(var);
			
			m_cmbPurpose.AddString( csTmp );
			
			m_pRecordset->MoveNext();
		}
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	m_cmbPurpose.SetCurSel( 0 );
	m_pRecordset->Close();
	
	
	// <> Fill ComboBox Owner
	try
	{
		m_pRecordset->Open("SELECT * FROM Userinfo",   
			theApp.m_pConnection.GetInterfacePtr(),	 // Get the Ptr of connect lib
			adOpenDynamic,
			adLockOptimistic,
			adCmdText);
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	
	m_cmbOwner.ResetContent();
	try
	{
		if(!m_pRecordset->BOF)
			m_pRecordset->MoveFirst();
		else
		{
			//AfxMessageBox("Table is NULL");
			return TRUE;
		}
		
		while(!m_pRecordset->adoEOF)
		{
			var = m_pRecordset->GetCollect("Name"); // txt
			if(var.vt != VT_NULL)
				csTmp = (LPCSTR)_bstr_t(var);
			
			m_cmbOwner.AddString( csTmp );
			
			m_pRecordset->MoveNext();
		}
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	m_cmbOwner.SetCurSel( 0 );
	m_pRecordset->Close();
	
	// <> set current date 
	m_dateBegin = CTime::GetCurrentTime();
	m_dateEnd = CTime::GetCurrentTime();
	

	// Init checkbox status
	CButton			*pBtn = NULL;
	CDateTimeCtrl	*pWnd = NULL;
	
	pBtn = (CButton*)GetDlgItem( IDC_CHK_FLOW );
	pBtn->SetCheck( 0 );
	m_cmbFlow.EnableWindow( FALSE );	
	
	pBtn = (CButton*)GetDlgItem( IDC_CHK_PURPOSE );
	pBtn->SetCheck( 0 );
	m_cmbPurpose.EnableWindow( FALSE );	
	
	pBtn = (CButton*)GetDlgItem( IDC_CHK_OWNER );
	pBtn->SetCheck( 0 );
	m_cmbOwner.EnableWindow( FALSE );	
	
	pBtn = (CButton*)GetDlgItem( IDC_CHK_DATE );
	pBtn->SetCheck( 0 );
	pWnd = (CDateTimeCtrl*)GetDlgItem( IDC_DATE_BEG );
	pWnd->EnableWindow( FALSE );
	pWnd = (CDateTimeCtrl*)GetDlgItem( IDC_DATE_END );
	pWnd->EnableWindow( FALSE );
	

	m_edComment.SetLimitText( 150 );	// order by account table
	
	UpdateData( FALSE );
	
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

CDlgSearch::~CDlgSearch()
{
	if( m_pRecordset != NULL )
	{
		if( m_pRecordset->State )
			m_pRecordset->Close();
		m_pRecordset = NULL;
	}
}

// 
// Get search conditions and compose into SQL.
//--------------------------------------------------------------
void CDlgSearch::OnSearch() 
{
	CDataFile		IniDF( MONEY_CFG );
	CButton			*pBtn = NULL;
	CHAR			chSQL[INI_MAX_BUFLEN] = { 0 };
	CHAR			chAND[6];
	CTime			date;
	CString			csSeg, csItem[2];
	CString			csTemp[ACCOUNT_COLUMNS];
	
	
	UpdateData( TRUE );
	
	strcpy( chAND, "AND " );
	
	// <> Get data from ctrl and fill into csTemp[] array
	pBtn = (CButton*)GetDlgItem( IDC_CHK_FLOW );
	if( pBtn->GetCheck() == 1 ) // checked 
	{
		m_cmbFlow.GetLBText( m_cmbFlow.GetCurSel(), csTemp[flowclass] );
	}

	pBtn = (CButton*)GetDlgItem( IDC_CHK_PURPOSE );
	if( pBtn->GetCheck() == 1 ) // checked 
	{
		m_cmbPurpose.GetLBText( m_cmbPurpose.GetCurSel(), csTemp[purpose] );
	}

	pBtn = (CButton*)GetDlgItem( IDC_CHK_OWNER );
	if( pBtn->GetCheck() == 1 ) // checked 
	{
		m_cmbOwner.GetLBText( m_cmbOwner.GetCurSel(), csTemp[owner] );
	}
	
	pBtn = (CButton*)GetDlgItem( IDC_CHK_DATE );
	if( pBtn->GetCheck() == 1 ) // checked 
	{
		if( m_dateBegin.GetTime() > m_dateEnd.GetTime() )
		{
			MessageBox( "Begin date is more later than End date!", "Warning", MB_ICONWARNING );
			return ;
		}
		date = m_dateBegin.GetTime();
		if( wtkGetSysLanguage() == WTK_BIG5 ) 
		{
			csItem[0] = date.Format( "%Y/%m/%d" );	// in Big5 system, is "2005/7/12"
			if( csItem[0].GetAt(8) == '0' ) 
				csItem[0].Delete( 8, 1 );
			if( csItem[0].GetAt(5) == '0' ) 
				csItem[0].Delete( 5, 1 );
		}
		else
			csItem[0] = date.Format( "%Y-%m-%d" );	// in GB system, is "2005-7-12"
		
		date = m_dateEnd.GetTime();
		if( wtkGetSysLanguage() == WTK_BIG5 ) 
		{
			csItem[1] = date.Format( "%Y/%m/%d" );	// in Big5 system, is "2005/7/12"
			if( csItem[1].GetAt(8) == '0' ) 
				csItem[1].Delete( 8, 1 );
			if( csItem[1].GetAt(5) == '0' ) 
				csItem[1].Delete( 5, 1 );
		}
		else
			csItem[1] = date.Format( "%Y-%m-%d" );	// in GB system, is "2005-7-12"
	}
	
	// <> if NULL, don't include it.
	m_edAccount.GetWindowText( csTemp[amount] );
	m_edComment.GetWindowText( csTemp[comment] );
	

	// <> compose SQL segment
	if( !csTemp[amount].IsEmpty() ) 
	{
		csSeg += chAND;
		switch( m_iCompare ) 
		{
		case -1:
			csSeg += "Amount <=" + csTemp[amount] + " ";
			break ;
		
		case 0:
			csSeg += "Amount=" + csTemp[amount] + " ";
			break ;

		case 1:
			csSeg += "Amount >=" + csTemp[amount] + " ";
			break ;
			
		default :
			csSeg += "Amount=" + csTemp[amount] + " ";
			break ;
		}
	}

	if( !csTemp[flowclass].IsEmpty() ) 
	{
		csSeg += chAND;
		csSeg += "FlowClass='" + csTemp[flowclass] + "' ";
	}
	
	if( !csTemp[purpose].IsEmpty() ) 
	{
		csSeg += chAND;
		csSeg += "Purpose='" + csTemp[purpose] + "' ";
	}
	
	if( !csTemp[owner].IsEmpty() ) 
	{
		csSeg += chAND;
		csSeg += "Owner='" + csTemp[owner] + "' ";
	}
	
	if( !csTemp[comment].IsEmpty() ) 
	{
		csSeg += chAND;
		if( m_bExactMatch )
			csSeg += "Comment='" + csTemp[comment] + "' ";
		else
			csSeg += "Comment like '%" + csTemp[comment] + "%' ";
	}
	
	// check range 
	if( !csItem[0].IsEmpty() && !csItem[1].IsEmpty() ) 
	{
		sprintf( chSQL, "Date >=#%s# AND Date <=#%s# ", csItem[0], csItem[1] );
		csSeg += chAND;
		csSeg += chSQL;
	}
	
	// <> fstream into  ini file
	if( !csSeg.IsEmpty() )
	{
		// <> check length and cut overlength
		if( csSeg.GetLength() >= INI_MAX_BUFLEN )
		{
			LPTSTR		pMatch = NULL;
			
			LPTSTR		pLast = NULL;
			
			strncpy( chSQL, csSeg, INI_MAX_BUFLEN - 1 );
			
			pMatch = strstr( chSQL, "AND" );		
			while( pMatch )
			{
				pLast = pMatch; // retain last laster p
				pMatch += 3;	
				pMatch = strstr( pMatch, "AND" );
			}
			
			if( pLast )
				*pLast = 0;
		}
		else
			strcpy( chSQL, csSeg ); 
		
		// chSQL+3 to skip the first "AND"
		IniDF.SetValue( "SQL", chSQL+3, "SQL segment for search", "SQL segment" );
	}
	else
		IniDF.SetValue( "SQL", "", "SQL segment for search", "SQL segment" );
	
	// 0 is FALSE ; 1 is TRUE;
	IniDF.SetInt( "ExactMatch", m_bExactMatch,  "exact or inexact for search", "SQL segment" );
	
	
	IniDF.Save();
	

	// send reshow 
	CDialog::OnOK();
}

// 
//--------------------------------------------------------------
void CDlgSearch::OnRdoExact() 
{
	m_bExactMatch = TRUE;
}

// 
//--------------------------------------------------------------
void CDlgSearch::OnRdoInexact() 
{
	m_bExactMatch = FALSE;
}

// 
//--------------------------------------------------------------
void CDlgSearch::OnChkFlow() 
{
	CButton *pBtn = (CButton*)GetDlgItem( IDC_CHK_FLOW );
	
	
	if( pBtn->GetCheck() == 0 ) //  unchecked
		m_cmbFlow.EnableWindow( FALSE );
	else if( pBtn->GetCheck() == 1 ) // checked
	{
		m_cmbFlow.EnableWindow( TRUE );
		m_cmbFlow.SetFocus();
	}
}

// 
//--------------------------------------------------------------
void CDlgSearch::OnChkPurpose() 
{
	CButton *pBtn = (CButton*)GetDlgItem( IDC_CHK_PURPOSE );
	
	
	if( pBtn->GetCheck() == 0 ) //  unchecked
		m_cmbPurpose.EnableWindow( FALSE );
	else if( pBtn->GetCheck() == 1 ) // checked
	{
		m_cmbPurpose.EnableWindow( TRUE );
		m_cmbPurpose.SetFocus();
	}
}

// 
//--------------------------------------------------------------


// 
//--------------------------------------------------------------
void CDlgSearch::OnChkOwner() 
{
	CButton *pBtn = (CButton*)GetDlgItem( IDC_CHK_OWNER );
	
	
	if( pBtn->GetCheck() == 0 ) //  unchecked
		m_cmbOwner.EnableWindow( FALSE );
	else if( pBtn->GetCheck() == 1 ) // checked
	{
		m_cmbOwner.EnableWindow( TRUE );
		m_cmbOwner.SetFocus();
	}
}

// 
//--------------------------------------------------------------
void CDlgSearch::OnChkDate() 
{
	CDateTimeCtrl *pDatebegin = (CDateTimeCtrl*)GetDlgItem( IDC_DATE_BEG );
	CDateTimeCtrl *pDateend = (CDateTimeCtrl*)GetDlgItem( IDC_DATE_END );
	CButton *pBtn = (CButton*)GetDlgItem( IDC_CHK_DATE );
	
	
	if( pBtn->GetCheck() == 0 ) //  unchecked
	{
		pDatebegin->EnableWindow( FALSE );
		pDateend->EnableWindow( FALSE );
	}
	else if( pBtn->GetCheck() == 1 ) // checked
	{
		pDatebegin->EnableWindow( TRUE );
		pDateend->EnableWindow( TRUE );
		pDatebegin->SetFocus();
	}	
}

// 
//--------------------------------------------------------------
void CDlgSearch::OnSelchangeCmbFlow() 
{
	_variant_t		var;
	CString			csTmp;
	CString			csSQL;
	
	
	// <> Fill ComboBox Purpose
	m_cmbFlow.GetLBText( m_cmbFlow.GetCurSel(), csTmp );
	
	csSQL = "SELECT Usename FROM Purpose WHERE Flowclass='" + csTmp + "' ORDER BY Usename ASC";
	var = csSQL;
	try
	{
		m_pRecordset->Open( var,					// const _variant_t & Source
			theApp.m_pConnection.GetInterfacePtr(),	// Get the Ptr of connect lib
			adOpenDynamic,
			adLockOptimistic,
			adCmdText);
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	
	m_cmbPurpose.ResetContent();
	try
	{
		if(!m_pRecordset->BOF)
			m_pRecordset->MoveFirst();
		else
		{
			//AfxMessageBox("Table is NULL");
			return ;
		}
		
		while(!m_pRecordset->adoEOF)
		{
			var = m_pRecordset->GetCollect("Usename"); // txt
			if(var.vt != VT_NULL)
				csTmp = (LPCSTR)_bstr_t(var);
			
			m_cmbPurpose.AddString( csTmp );
			
			m_pRecordset->MoveNext();
		}
	}
	catch(_com_error *e)
	{
		AfxMessageBox(e->ErrorMessage());
	}
	
	m_cmbPurpose.SetCurSel( 0 );
	m_pRecordset->Close();
}

// 
// <=
//--------------------------------------------------------------
void CDlgSearch::OnRdoLess() 
{
	m_iCompare = -1; 
}

// 
// ==
//--------------------------------------------------------------
void CDlgSearch::OnRdoEqual() 
{
	m_iCompare = 0; 
}

// 
// >=
//--------------------------------------------------------------
void CDlgSearch::OnRdoMore() 
{
	m_iCompare = 1; 
}
